import { SysMLUtilHelper, MofModelHelper, GraphHelper } from 'src/api/sysml-imports';
import { GraphNodeUtil } from '@/pages/mxgraph/GraphNodeUtil';
import ResizeUtil from '@/pages/mxgraph/resizeUtil';
import { getStyleObj, getStyleStr } from "src/util/common";
import { FlyTDUtils } from '@/pages/mxgraph/behaviors/FlyDiagram/FlyTDUtils';
import { validate } from '../config/PropertyValidate';
import { behaviors } from '@/pages/mxgraph/behaviors';
import { dumpLog } from '@/constants/ErrorConfig';

export class PropertyUtil {
  /**
 * 获取graphNode属性
 * @param graphNode
 * @param property property或者property的name
 */
  static getNodePropertyValue(graphNode:GraphNode, property:string | any, autoInit = true){
    autoInit && GraphNodeUtil.initProperty(graphNode);
    const graphNodeModel = graphNode.model;
    if (!graphNodeModel) {
      console.error('模型缺失');
      return '';
    }
    if (typeof property === 'string'){
      const properties = graphNode.properties.toArray();  //// graphProperty;
      property = properties.find(p => p.config.key === property || p.config.name === property);
    }
    if (property == null) return '';

    let result = property.getValue();
    if (result){
      const editType = property.config.editType;
      if (editType === 'tree-muti-select') {
        result = result.toArray();
        //// .filter(it => SysMLUtilHelper.getModelById(it.id, app.activeProjectId));
      } else if (editType === 'single-select') {
        if (typeof result !== "string") {
          if (SysMLUtilHelper.isIEnumerationLiteral(result) || (property.property && SysMLUtilHelper.isIEnumeration(property.property.getType()))) {
            result = result.getQualifiedName();
          } else {
            result = result.toString();
          }
        }
      } else if (editType === 'tree-single-select'){
        //// console.log(result);
        //// result = SysMLUtilHelper.getModelById(result.id, app.activeProjectId);
      }
    }
    return result;
  }

  /**
   * 更新单个属性的值
   * @param value 修改的值
   * @param graphProperty 属性
   * @param currentGraphNode 当前模型的Node
   * @param graphNodes 选择的graphNode（可以为空，只在有选择器控件的属性上面有效）
   */
  static updateRow(value: any, graphProperty: any, currentGraphNode: GraphNode, graphNodes: any, freshGraph = true) {
    dumpLog("修改值:", value);

    const selectedElement = currentGraphNode.model;
    const backupValue = graphProperty.getValue();
    if (graphProperty.fromStereotype) {
      if (!SysMLUtilHelper.isPrimitiveTypes(graphProperty.property.getType())) { //// 对象类型
        const typeName = graphProperty.typeName;
        //// 0 source 1 target
        let directType = 0;
        if (SysMLUtilHelper.isEdgeReverse(graphProperty.property)) {
          directType = 1;
        }
        const existsEdges = GraphHelper.getGraphEdgeByTypeName(typeName, currentGraphNode, directType);
        let currentEdges = [];
        let deletedEdges = [];
        if (graphNodes) {
          //// 1. 设置新的edge
          graphNodes.forEach((item, index, array) => {
            if (SysMLUtilHelper.isEdgeReverse(graphProperty.property)) {
              currentEdges.push(GraphHelper.createGraphEdge(app.activeProjectId, typeName, item, currentGraphNode));
            } else {
              currentEdges.push(GraphHelper.createGraphEdge(app.activeProjectId, typeName, currentGraphNode, item));
            }
          });
        }
        //// 2. 获得不需要的edge
        if (existsEdges) {
          deletedEdges = existsEdges.filter(function(v, i, arr){
            return currentEdges.indexOf(v) < 0;
          });
          //// deletedEdges = existsEdges.concat(currentEdges).filter(function(v, i, arr) {
          ////   return arr.indexOf(v) === arr.lastIndexOf(v);
          //// });
        }
        console.log("deletedEdges........................", deletedEdges);
        //// 3. 删除不需要的edge
        if (deletedEdges) {
          deletedEdges.forEach((item, index, array) => {
            GraphHelper.removeGraphElement(item);
          });
        }
      }

      if (Array.isArray(value)) { //// 数组值处理
        //// UMLClassificationHelper.updateSlotValue(selectedElement, graphProperty.property, value);
        graphProperty.setValue(value);
      } else {
        
        const result = validate(currentGraphNode, value, graphProperty); 
        if ( result === true){
          graphProperty.setValue([value]);
        } else {
          app.$messageBox.warn({ 
            text: result,
            id: 110,
            title: '赋值错误'
          });
          graphProperty.setValue([backupValue]);
        }
        
        //// UMLClassificationHelper.updateSlotValue(selectedElement, graphProperty.property, [value]);
      }
    } else {
      if (graphNodes != null && graphNodes.length > 0) {
        graphProperty.setValue(graphNodes);
        //// ModelPropertyMutator.modifyProperty(currentGraphNode, graphProperty.config, graphNodes);
      } else {
        graphProperty.setValue(value);
        //// ModelPropertyMutator.modifyProperty(currentGraphNode, graphProperty.config, value);
      }
    }
    app.$bus.emit('project-modified');
    const typeName = currentGraphNode.getTypeName();
    behaviors.get(typeName).afterPropertyChange(currentGraphNode, graphProperty, freshGraph);
    //// if (freshGraph){
    ////   const name = currentGraphNode.getTypeName();
    ////   ResizeUtil.updateNodeShapes(currentGraphNode, false);
    ////   app.$bus.emit('fresh-graph-debounce');
    ////   const styleUpdateConfig = {
    ////     'TimeLine': [
    ////       "起点",
    ////       "终点",
    ////       "步长",
    ////       "名称"
    ////     ],
    ////     'CommandAction': [
    ////       "发生时间点",
    ////       "指令来源",
    ////       "电信号"
    ////     ]
    ////   };
    ////   if (Reflect.has(styleUpdateConfig, name) && styleUpdateConfig[name].includes(graphProperty.config.name) ){
    ////     const style = getStyleObj(currentGraphNode.childLeafElement[0].box.style);
    ////     if (Reflect.has(style, 'magic')){
    ////       Reflect.deleteProperty(style, 'magic');
    ////     } else {
    ////       style.magic = '1';
    ////     }
    ////     currentGraphNode.childLeafElement[0].box.style = getStyleStr(style);
    ////     if (name === 'TimeLine'){
    ////       FlyTDUtils.AdjustChildShape(currentGraphNode, 'CommandAction');
    ////     }
    ////     if (name === 'CommandAction'){
    ////       FlyTDUtils.AdjustSelf(currentGraphNode);
    ////     }
    ////   }
      
    //// }

  }

  /**
 * 初始化属性配置信息，因为stereotype的属性可以动态修改
 * @param graphProperty GraphNode的属性（GraphProperty）
 */
  static initPropertyConfig(graphProperty: any) {
    SysMLUtilHelper.initConfigByProperty(graphProperty);
  }

  /**
   * 通过属性key修改属性值
   * @param graphNode 当前树节点
   * @param propertyKey 属性名称
   * @param value 属性值 ////
   */
  static updateProperty(graphNode:GraphNode, propertyKey:string, value:any, freshGraph = true) {
    GraphNodeUtil.initProperty(graphNode);
    const properties = graphNode.properties.toArray();  //// graphProperty;
    let property = properties.find(p => p.config.key === propertyKey);
    this.updateRow(value, property, graphNode, null, freshGraph);
  }

  /**
   * 通过属性名修改属性值
   * @param graphNode 当前树节点
   * @param propertyName 属性名称
   * @param value 属性值 ////
   */
  static updatePropertyByName(graphNode:GraphNode, propertyName:string, value:any) {
    GraphNodeUtil.initProperty(graphNode);
    const properties = graphNode.properties.toArray();  //// graphProperty;
    let property = properties.find(p => p.config.key === propertyName);
    this.updateRow(value, property, graphNode, null);
  }
}
